package com.zyh.demo.utils;

import com.zyh.demo.domain.Book;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @Author zyh
 * @Date 2024/8/14 15:03
 * @Description
 */

public class MyJson {
    //1.将一个json对象转为一个JSON字符串
    public static String domainToJsonString(Object param) {
        if (param == null) {
            return "{}";
        }
        StringBuilder sb = null;
        try {
            //通过对象获取字节码文件
            Class c = param.getClass();
            //拿到所有属性
            Field[] declaredFields = c.getDeclaredFields();
            //准备一个StringBuilder
            sb = new StringBuilder();
            sb.append("{");
            //遍历集合，拿到各个属性
            for (Field declaredField : declaredFields) {
                //打开访问开关
                declaredField.setAccessible(true);
                //拿到属性名
                String fieldName = declaredField.getName();
                if (fieldName.equals("serialVersionUID")) {
                    continue;
                }
                //改装属性名
                fieldName = "\"" + fieldName + "\"";
                //拿到属性值
                Object fieldValue = declaredField.get(param);
                //判断属性值
                if (fieldValue instanceof String || fieldValue instanceof StringBuilder || fieldValue instanceof StringBuffer) {
                    fieldValue = "\"" + fieldValue + "\"";
                }
                if (fieldValue instanceof Date) {
                    fieldValue = ((Date) fieldValue).getTime();
                }
                sb.append(fieldName + ":" + fieldValue + ",");
            }
            //循环结束后删除最后一个逗号
            sb.deleteCharAt(sb.length() - 1);
            sb.append("}");
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return sb.toString();
    }

    //2.将一个Object对象数组/集合转为JSON字符串
    public static String multipleDomainToJsonString(Object param) {
        //将param转为集合
        List bookList = (List) param;
        //创建一个sb对象
        StringBuilder sb = new StringBuilder();
        sb.append("[");
        //遍历数组/集合
        for (Object books : bookList) {
            String s = domainToJsonString(books);//{"bName":"铁山靠","author":"cxk","price":23.0,"createTime":1723624277301}
            s = s + ",";
            sb.append(s);
        }
        //删除最后一个逗号
        sb.deleteCharAt(sb.length() - 1);
        sb.append("]");

        return sb.toString();
    }

    //3.将一个对象（普通对象|集合对象）转为JSON字符串
    public static String objectToJsonString(Object param) {
        if (param instanceof Map) {
            throw new IllegalArgumentException("不能传入双列集合！");
        }
        if (param instanceof Collection) {
            return multipleDomainToJsonString(param);
        }
        return domainToJsonString(param);
    }


    //4.将一个对象的JSON字符串解析成Java对象
    //"{"bName":"坤家拳","author":"cxk","price":23.0,"createTime":1723624886176}"
    public static Book jsonStringToDomain(String str) {
        try {
            //去掉左右两边的{}
            str = str.substring(1);
            str = str.substring(0, str.length() - 1);//"bName":"坤家拳","author":"cxk","price":23.0,"createTime":1723624886176
            //按照逗号切割
            String[] split = str.split(",");//"bName":"坤家拳"
            //通过反射创建一个空的Book对象
            //获取字节码对象
            Class c = Book.class;
            //调用构造方法
            Book book = (Book) c.getDeclaredConstructor().newInstance();
            for (String keyValueStr : split) {
                //按照冒号:切割
                String[] keyStr = keyValueStr.split(":");//"bName"
                //数组[0]位置是属性名,数组[1]号位置是属性值
                String fieldName = keyStr[0].replace("\"", "");
                String fieldValue = keyStr[1].replace("\"", "");
                //拿到每一个属性名
                Field declaredField = c.getDeclaredField(fieldName);
                //封装为Book对象
                //打开访问开关
                declaredField.setAccessible(true);
                //进行封装
                //将Value进行转换
                if (declaredField.getType().getName().contains("String")) {
                    declaredField.set(book, fieldValue);
                } else if (declaredField.getType().getName().contains("Date")) {
                    long dateFieldValue = Long.parseLong(fieldValue);
                    Date date = new Date(dateFieldValue);
                    declaredField.set(book, date);
                } else if (declaredField.getType().getName().contains("Double")) {
                    double doubleFieldValue = Double.parseDouble(fieldValue);
                    declaredField.set(book, doubleFieldValue);
                }
            }
            return book;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    //5.将一个集合对象的JSON字符串解析成Java中的集合对象
    //[{"bName":"三国演义","author":"罗贯中","price":23.0,"createTime":1723627131305},{"bName":"西游记","author":"吴承恩","price":25.0,"createTime":1723627131305}{"bName":"红楼梦","author":"曹雪芹","price":26.0,"createTime":1723627131305}]
    public static List<Book> jsonStringToList(String str) {
        List<Book> list = new ArrayList<>();
        str = str.substring(1);
        str = str.substring(0, str.length() - 2);
        //根据逗号切割为一个数组
        String[] split = str.split("},\\{");
        //System.out.println(Arrays.toString(split));
        StringBuilder sb = new StringBuilder();
        sb.append(split[0] + "}");
        for (String item : split) {
            Book book = jsonStringToDomain(item);
            list.add(book);
        }
        return list;
    }
}